#lang racket


(provide 
 (struct-out primitive-type)
 (struct-out line-primitive-type)
 (struct-out surface-primitive-type)
 (struct-out solid-primitive-type)
 
 (struct-out align-type)
 (struct-out center-align-type)
 (struct-out x-pos-align-type)
 (struct-out x-neg-align-type)
 (struct-out y-pos-align-type)
 (struct-out y-neg-align-type)
 (struct-out z-pos-align-type)
 (struct-out z-neg-align-type)
 make-align-type
 
 (struct-out on-type)
 (struct-out x-pos-on-type)
 (struct-out x-neg-on-type)
 (struct-out y-pos-on-type)
 (struct-out y-neg-on-type)
 (struct-out z-pos-on-type)
 (struct-out z-neg-on-type)
 make-on-type
 
 (struct-out projection-type)
 (struct-out ortho-projection-type)
 (struct-out perspective-projection-type)
 
 (struct-out spline-type)
 (struct-out auto-spline-type)
 (struct-out tangent-spline-type)
 
 (struct-out view-type)
 (struct-out auto-view-type)
 (struct-out manual-view-type))


; primitive-type

(struct primitive-type ())
(struct line-primitive-type primitive-type ())
(struct surface-primitive-type primitive-type ())
(struct solid-primitive-type primitive-type ())


; align-type

(define (align-type-msg type)
  (format "Parameter must be one of 'center, '+x, '-x, '+y, '-y, '+z, '-z, 'back, 'bottom, 'front, 'left, 'right or 'top, given ~A" type))

(struct align-type ()
  #:constructor-name new-align-type)

(struct center-align-type align-type ())
(struct x-pos-align-type align-type ())
(struct x-neg-align-type align-type ())
(struct y-pos-align-type align-type ())
(struct y-neg-align-type align-type ())
(struct z-pos-align-type align-type ())
(struct z-neg-align-type align-type ())

(define (make-align-type sym)
  (case sym
    ('center (center-align-type))
    ((+x right) (x-pos-align-type))
    ((-x left) (x-neg-align-type))
    ((+y back) (y-pos-align-type))
    ((-y front) (y-neg-align-type))
    ((+z top) (z-pos-align-type))
    ((-z bottom) (z-neg-align-type))
    (else
     (error 'make-align-type (align-type-msg sym)))))

; /align-type


; on-type

(define (on-type-msg type)
  (format "Parameter must be one of '+x, '-x, '+y, '-y, '+z, '-z, 'back, 'bottom, 'front, 'left, 'right or 'top, given ~A" type))

(struct on-type ())
(struct x-pos-on-type on-type ())
(struct x-neg-on-type on-type ())
(struct y-pos-on-type on-type ())
(struct y-neg-on-type on-type ())
(struct z-pos-on-type on-type ())
(struct z-neg-on-type on-type ())

(define (make-on-type sym)
  (case sym
    ((+x right) (x-pos-on-type))
    ((-x left) (x-neg-on-type))
    ((+y back) (y-pos-on-type))
    ((-y front) (y-neg-on-type))
    ((+z top) (z-pos-on-type))
    ((-z bottom) (z-neg-on-type))
    (else
     (error 'make-on-type (on-type-msg sym)))))


; projection type

(struct projection-type ())
(struct ortho-projection-type ())
(struct perspective-projection-type ())


; spline type

(struct spline-type ())
(struct auto-spline-type spline-type ())
(struct tangent-spline-type spline-type (begin-tangent end-tangent))


; view-type

(struct view-type ())
(struct auto-view-type view-type (direction))
(struct manual-view-type view-type (center target))